/*
 * LinkedList.h
 *
 *  Created on: Oct 1, 2010
 *      Author: Jacob
 */

#ifndef LINKEDLIST_H_
#define LINKEDLIST_H_
#include "Node.h"
#include <string>
#include <sstream>
using std::string;
using std::ostringstream;
using std::stringstream;
#include <iostream>
using std::cout;

class LinkedList
{
public:
	static LinkedList* newLinkedList(bool circularlyLinked);
	void addToHead(string placeholder);
	void addToHead(Node* nodeToBeAdded);
	void addToTail(string placeholder);
	void addToTail(Node* nodeToBeAdded);
	void insert(string placeholder, int position);
	void insert(Node* nodeToBeInserted, int position);
	void removeFromHead();
	void removeFromTail();
	void remove(int position);
	void remove(Node* nodeToBeRemoved);
	Node* search(string value);
	Node* search(Node* nodeToBeFound);
	Node* getCurrent();
	void setCurrent(Node* current);
	int getSize();
	string toString();
	void iterate();
	void setCurrentToHead();
	LinkedList& operator++();
	virtual ~LinkedList();
private:
	int size;
	Node* head;
	Node* tail;
	Node* current;
	bool circularlyLinked;
	bool dummyTailRemoved;
	bool dummyHeadRemoved;
	bool overrideNullHead(Node* nodeToBeAdded);
	void replaceNullHead(Node* newHead);
	bool overrideNullTail(Node* nodeToBeAdded);
	void replaceNullTail(Node* newTail);
	void findPositionAndInsertNode(Node* nodeToBeInserted, int position);
	void insertNode(Node* nodeToBeInserted);
	bool removeFromHeadOrTail(int position);
	bool removeFromHeadOrTail(Node* nodeToBeChedked);
	Node* getNodeAtPosition(int position);
	void prepareNodeForDeletion(Node* nodeToBeDeleted);
	void addNodeToHead(Node* nodeToBeAdded);
	void addNodeToTail(Node* nodeToBeAdded);
	void deleteNode(Node* nodeToBeDeleted);
	void modifySize(int value);
	void makeListCircularlyLinked();
	Node* constructNodeFromData(string placeholder);
	LinkedList(bool circularlyLinked);
};

#endif /* LINKEDLIST_H_ */
